/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package Control;

import Control.exceptions.NonexistentEntityException;
import Control.exceptions.PreexistingEntityException;
import java.io.Serializable;
import javax.persistence.Query;
import javax.persistence.EntityNotFoundException;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import Entidades.Habitacion;
import Entidades.Pasajero;
import java.util.ArrayList;
import java.util.List;
import Entidades.Factura;
import Entidades.Consumo;
import Entidades.Estadia;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;

/**
 *
 * @author USUARIO
 */
public class EstadiaJpaController implements Serializable {

    public EstadiaJpaController(EntityManagerFactory emf) {
        this.emf = emf;
    }
    private EntityManagerFactory emf = null;

    public EntityManager getEntityManager() {
        return emf.createEntityManager();
    }

    public void create(Estadia estadia) throws PreexistingEntityException, Exception {
        if (estadia.getPasajeroList() == null) {
            estadia.setPasajeroList(new ArrayList<Pasajero>());
        }
        if (estadia.getFacturaList() == null) {
            estadia.setFacturaList(new ArrayList<Factura>());
        }
        if (estadia.getConsumoList() == null) {
            estadia.setConsumoList(new ArrayList<Consumo>());
        }
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Habitacion habitacion = estadia.getHabitacion();
            if (habitacion != null) {
                habitacion = em.getReference(habitacion.getClass(), habitacion.getNumero());
                estadia.setHabitacion(habitacion);
            }
            List<Pasajero> attachedPasajeroList = new ArrayList<Pasajero>();
            for (Pasajero pasajeroListPasajeroToAttach : estadia.getPasajeroList()) {
                pasajeroListPasajeroToAttach = em.getReference(pasajeroListPasajeroToAttach.getClass(), pasajeroListPasajeroToAttach.getIdPasajero());
                attachedPasajeroList.add(pasajeroListPasajeroToAttach);
            }
            estadia.setPasajeroList(attachedPasajeroList);
            List<Factura> attachedFacturaList = new ArrayList<Factura>();
            for (Factura facturaListFacturaToAttach : estadia.getFacturaList()) {
                facturaListFacturaToAttach = em.getReference(facturaListFacturaToAttach.getClass(), facturaListFacturaToAttach.getNroFactura());
                attachedFacturaList.add(facturaListFacturaToAttach);
            }
            estadia.setFacturaList(attachedFacturaList);
            List<Consumo> attachedConsumoList = new ArrayList<Consumo>();
            for (Consumo consumoListConsumoToAttach : estadia.getConsumoList()) {
                consumoListConsumoToAttach = em.getReference(consumoListConsumoToAttach.getClass(), consumoListConsumoToAttach.getIdConsumo());
                attachedConsumoList.add(consumoListConsumoToAttach);
            }
            estadia.setConsumoList(attachedConsumoList);
            em.persist(estadia);
            if (habitacion != null) {
                habitacion.getEstadiaList().add(estadia);
                habitacion = em.merge(habitacion);
            }
            for (Pasajero pasajeroListPasajero : estadia.getPasajeroList()) {
                pasajeroListPasajero.getEstadiaList().add(estadia);
                pasajeroListPasajero = em.merge(pasajeroListPasajero);
            }
            for (Factura facturaListFactura : estadia.getFacturaList()) {
                Estadia oldIdEstadiaOfFacturaListFactura = facturaListFactura.getIdEstadia();
                facturaListFactura.setIdEstadia(estadia);
                facturaListFactura = em.merge(facturaListFactura);
                if (oldIdEstadiaOfFacturaListFactura != null) {
                    oldIdEstadiaOfFacturaListFactura.getFacturaList().remove(facturaListFactura);
                    oldIdEstadiaOfFacturaListFactura = em.merge(oldIdEstadiaOfFacturaListFactura);
                }
            }
            for (Consumo consumoListConsumo : estadia.getConsumoList()) {
                Estadia oldEstadiaOfConsumoListConsumo = consumoListConsumo.getEstadia();
                consumoListConsumo.setEstadia(estadia);
                consumoListConsumo = em.merge(consumoListConsumo);
                if (oldEstadiaOfConsumoListConsumo != null) {
                    oldEstadiaOfConsumoListConsumo.getConsumoList().remove(consumoListConsumo);
                    oldEstadiaOfConsumoListConsumo = em.merge(oldEstadiaOfConsumoListConsumo);
                }
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            if (findEstadia(estadia.getIdEstadia()) != null) {
                throw new PreexistingEntityException("Estadia " + estadia + " already exists.", ex);
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void edit(Estadia estadia) throws NonexistentEntityException, Exception {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Estadia persistentEstadia = em.find(Estadia.class, estadia.getIdEstadia());
            Habitacion habitacionOld = persistentEstadia.getHabitacion();
            Habitacion habitacionNew = estadia.getHabitacion();
            List<Pasajero> pasajeroListOld = persistentEstadia.getPasajeroList();
            List<Pasajero> pasajeroListNew = estadia.getPasajeroList();
            List<Factura> facturaListOld = persistentEstadia.getFacturaList();
            List<Factura> facturaListNew = estadia.getFacturaList();
            List<Consumo> consumoListOld = persistentEstadia.getConsumoList();
            List<Consumo> consumoListNew = estadia.getConsumoList();
            if (habitacionNew != null) {
                habitacionNew = em.getReference(habitacionNew.getClass(), habitacionNew.getNumero());
                estadia.setHabitacion(habitacionNew);
            }
            List<Pasajero> attachedPasajeroListNew = new ArrayList<Pasajero>();
            for (Pasajero pasajeroListNewPasajeroToAttach : pasajeroListNew) {
                pasajeroListNewPasajeroToAttach = em.getReference(pasajeroListNewPasajeroToAttach.getClass(), pasajeroListNewPasajeroToAttach.getIdPasajero());
                attachedPasajeroListNew.add(pasajeroListNewPasajeroToAttach);
            }
            pasajeroListNew = attachedPasajeroListNew;
            estadia.setPasajeroList(pasajeroListNew);
            List<Factura> attachedFacturaListNew = new ArrayList<Factura>();
            for (Factura facturaListNewFacturaToAttach : facturaListNew) {
                facturaListNewFacturaToAttach = em.getReference(facturaListNewFacturaToAttach.getClass(), facturaListNewFacturaToAttach.getNroFactura());
                attachedFacturaListNew.add(facturaListNewFacturaToAttach);
            }
            facturaListNew = attachedFacturaListNew;
            estadia.setFacturaList(facturaListNew);
            List<Consumo> attachedConsumoListNew = new ArrayList<Consumo>();
            for (Consumo consumoListNewConsumoToAttach : consumoListNew) {
                consumoListNewConsumoToAttach = em.getReference(consumoListNewConsumoToAttach.getClass(), consumoListNewConsumoToAttach.getIdConsumo());
                attachedConsumoListNew.add(consumoListNewConsumoToAttach);
            }
            consumoListNew = attachedConsumoListNew;
            estadia.setConsumoList(consumoListNew);
            estadia = em.merge(estadia);
            if (habitacionOld != null && !habitacionOld.equals(habitacionNew)) {
                habitacionOld.getEstadiaList().remove(estadia);
                habitacionOld = em.merge(habitacionOld);
            }
            if (habitacionNew != null && !habitacionNew.equals(habitacionOld)) {
                habitacionNew.getEstadiaList().add(estadia);
                habitacionNew = em.merge(habitacionNew);
            }
            for (Pasajero pasajeroListOldPasajero : pasajeroListOld) {
                if (!pasajeroListNew.contains(pasajeroListOldPasajero)) {
                    pasajeroListOldPasajero.getEstadiaList().remove(estadia);
                    pasajeroListOldPasajero = em.merge(pasajeroListOldPasajero);
                }
            }
            for (Pasajero pasajeroListNewPasajero : pasajeroListNew) {
                if (!pasajeroListOld.contains(pasajeroListNewPasajero)) {
                    pasajeroListNewPasajero.getEstadiaList().add(estadia);
                    pasajeroListNewPasajero = em.merge(pasajeroListNewPasajero);
                }
            }
            for (Factura facturaListOldFactura : facturaListOld) {
                if (!facturaListNew.contains(facturaListOldFactura)) {
                    facturaListOldFactura.setIdEstadia(null);
                    facturaListOldFactura = em.merge(facturaListOldFactura);
                }
            }
            for (Factura facturaListNewFactura : facturaListNew) {
                if (!facturaListOld.contains(facturaListNewFactura)) {
                    Estadia oldIdEstadiaOfFacturaListNewFactura = facturaListNewFactura.getIdEstadia();
                    facturaListNewFactura.setIdEstadia(estadia);
                    facturaListNewFactura = em.merge(facturaListNewFactura);
                    if (oldIdEstadiaOfFacturaListNewFactura != null && !oldIdEstadiaOfFacturaListNewFactura.equals(estadia)) {
                        oldIdEstadiaOfFacturaListNewFactura.getFacturaList().remove(facturaListNewFactura);
                        oldIdEstadiaOfFacturaListNewFactura = em.merge(oldIdEstadiaOfFacturaListNewFactura);
                    }
                }
            }
            for (Consumo consumoListOldConsumo : consumoListOld) {
                if (!consumoListNew.contains(consumoListOldConsumo)) {
                    consumoListOldConsumo.setEstadia(null);
                    consumoListOldConsumo = em.merge(consumoListOldConsumo);
                }
            }
            for (Consumo consumoListNewConsumo : consumoListNew) {
                if (!consumoListOld.contains(consumoListNewConsumo)) {
                    Estadia oldEstadiaOfConsumoListNewConsumo = consumoListNewConsumo.getEstadia();
                    consumoListNewConsumo.setEstadia(estadia);
                    consumoListNewConsumo = em.merge(consumoListNewConsumo);
                    if (oldEstadiaOfConsumoListNewConsumo != null && !oldEstadiaOfConsumoListNewConsumo.equals(estadia)) {
                        oldEstadiaOfConsumoListNewConsumo.getConsumoList().remove(consumoListNewConsumo);
                        oldEstadiaOfConsumoListNewConsumo = em.merge(oldEstadiaOfConsumoListNewConsumo);
                    }
                }
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            String msg = ex.getLocalizedMessage();
            if (msg == null || msg.length() == 0) {
                Integer id = estadia.getIdEstadia();
                if (findEstadia(id) == null) {
                    throw new NonexistentEntityException("The estadia with id " + id + " no longer exists.");
                }
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void destroy(Integer id) throws NonexistentEntityException {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Estadia estadia;
            try {
                estadia = em.getReference(Estadia.class, id);
                estadia.getIdEstadia();
            } catch (EntityNotFoundException enfe) {
                throw new NonexistentEntityException("The estadia with id " + id + " no longer exists.", enfe);
            }
            Habitacion habitacion = estadia.getHabitacion();
            if (habitacion != null) {
                habitacion.getEstadiaList().remove(estadia);
                habitacion = em.merge(habitacion);
            }
            List<Pasajero> pasajeroList = estadia.getPasajeroList();
            for (Pasajero pasajeroListPasajero : pasajeroList) {
                pasajeroListPasajero.getEstadiaList().remove(estadia);
                pasajeroListPasajero = em.merge(pasajeroListPasajero);
            }
            List<Factura> facturaList = estadia.getFacturaList();
            for (Factura facturaListFactura : facturaList) {
                facturaListFactura.setIdEstadia(null);
                facturaListFactura = em.merge(facturaListFactura);
            }
            List<Consumo> consumoList = estadia.getConsumoList();
            for (Consumo consumoListConsumo : consumoList) {
                consumoListConsumo.setEstadia(null);
                consumoListConsumo = em.merge(consumoListConsumo);
            }
            em.remove(estadia);
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public List<Estadia> findEstadiaEntities() {
        return findEstadiaEntities(true, -1, -1);
    }

    public List<Estadia> findEstadiaEntities(int maxResults, int firstResult) {
        return findEstadiaEntities(false, maxResults, firstResult);
    }

    private List<Estadia> findEstadiaEntities(boolean all, int maxResults, int firstResult) {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            cq.select(cq.from(Estadia.class));
            Query q = em.createQuery(cq);
            if (!all) {
                q.setMaxResults(maxResults);
                q.setFirstResult(firstResult);
            }
            return q.getResultList();
        } finally {
            em.close();
        }
    }

    public Estadia findEstadia(Integer id) {
        EntityManager em = getEntityManager();
        try {
            return em.find(Estadia.class, id);
        } finally {
            em.close();
        }
    }

    public int getEstadiaCount() {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            Root<Estadia> rt = cq.from(Estadia.class);
            cq.select(em.getCriteriaBuilder().count(rt));
            Query q = em.createQuery(cq);
            return ((Long) q.getSingleResult()).intValue();
        } finally {
            em.close();
        }
    }
    
}
